package com.wanqh.reptitle.utils;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 使用easyExcel导入导出的工具
 *
 * @author: wanqh
 * @date: created in 2019/12/9 2:06 下午
 * @version: 6.0.0
 * @since: 6.0.0
 */
@Slf4j
public class EasyExcelUtil {
    private EasyExcelUtil() {
    }

    public static <T> void  export(final  HttpServletResponse response, final Map<String, List<T>> dataMap, final String fileName, final Class headClazz) throws IOException{
        String excelName = StrUtil.isEmpty(fileName) ? "列表.xlsx" : fileName + ".xlsx";
        if(CollUtil.isEmpty(dataMap)) {
            return;
        }
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(excelName, "UTF-8"));
        // 这个策略是 头是头的样式 内容是内容的样式
        HorizontalCellStyleStrategy horizontalCellStyleStrategy = getHorizonCellStyle();
        ExcelWriter build = EasyExcel.write(response.getOutputStream(), headClazz).registerWriteHandler(horizontalCellStyleStrategy).build();
        Set<Map.Entry<String, List<T>>> entries = dataMap.entrySet();
        int i = 0;
        for(Map.Entry<String, List<T>> entry : entries) {
            WriteSheet writeSheet = EasyExcel.writerSheet(i, entry.getKey()).build();
            build.write(entry.getValue(), writeSheet);
            i++;
        }
        // finish关闭流
        build.finish();
    }

    /**
     * 单个表个导出
     *
     * @param response
     * @param data      导出的数据
     * @param fileName  文件名称
     * @param headClazz 表头对应的pojo，字段上使用easyexcel的注解标识表头
     * @throws IOException
     */
    public static void exportSplitTime(final HttpServletResponse response, final List data, final String fileName, final Class headClazz) throws IOException {
        String excelName = StrUtil.isEmpty(fileName) ? "列表.xlsx" : fileName + new SimpleDateFormat("yyyyMMddHHmmss", Locale.ENGLISH).format(new Date()) + ".xlsx";
        dealExport(response, data, excelName, headClazz);
    }

    public static void export(final HttpServletResponse response, final List data, final String fileName, final Class headClazz) throws IOException {
        String excelName = StrUtil.isEmpty(fileName) ? "列表.xlsx" : fileName + ".xlsx";
        dealExport(response, data, excelName, headClazz);
    }

    private static void dealExport(final HttpServletResponse response, final List data, final String fileName, final Class headClazz) throws IOException{
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        // 这个策略是 头是头的样式 内容是内容的样式
        HorizontalCellStyleStrategy horizontalCellStyleStrategy = getHorizonCellStyle();
        Integer onePageMaxRow = 1048500;
        if (data.size() > onePageMaxRow) {
            ExcelWriter build = EasyExcel.write(response.getOutputStream(), headClazz).registerWriteHandler(horizontalCellStyleStrategy).build();
            for (int i = 0; i <= data.size()/onePageMaxRow; i++) {
                WriteSheet writeSheet = EasyExcel.writerSheet(i, "Sheet" + (i+1)).build();
                if((i+1) * onePageMaxRow >= data.size()) {
                    build.write(data.subList(i * onePageMaxRow, data.size()),writeSheet);
                } else {
                    build.write(data.subList(i* onePageMaxRow, (i+1) * onePageMaxRow),writeSheet);
                }
            }
            // finish关闭流
            build.finish();
        } else {
            EasyExcel.write(response.getOutputStream(), headClazz).registerWriteHandler(horizontalCellStyleStrategy)
                    .autoCloseStream(Boolean.TRUE).sheet("Sheet1").doWrite(data);
        }

    }

    public static HorizontalCellStyleStrategy  getHorizonCellStyle() {
        HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(getHeaderStyle(), getCellStyle());
        return horizontalCellStyleStrategy;
    }

    /**
     * 获取表头样式
     *
     * @return
     */
    private static WriteCellStyle getHeaderStyle() {
        // 头的策略
        WriteCellStyle titleStyle = new WriteCellStyle();
        titleStyle.setFillForegroundColor(IndexedColors.SKY_BLUE.getIndex());
        titleStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
        titleStyle.setBorderBottom(BorderStyle.THIN);
        titleStyle.setBorderLeft(BorderStyle.THIN);
        titleStyle.setBorderRight(BorderStyle.THIN);
        titleStyle.setBorderTop(BorderStyle.THIN);
        titleStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        WriteFont titleFont = new WriteFont();
        titleFont.setColor(IndexedColors.VIOLET.getIndex());
        titleFont.setFontHeightInPoints(Short.valueOf("11"));
        titleFont.setBold(true);
        // 把字体应用到当前的样式
//        titleFont.setFontHeightInPoints((short)20);
        titleStyle.setWriteFont(titleFont);
        return titleStyle;
    }

    /**
     * 获取表格样式
     *
     * @return
     */
    private static WriteCellStyle getCellStyle() {
        // 内容的策略
        WriteCellStyle cellStyle = new WriteCellStyle();
        // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定
        cellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
        // 背景绿色
        cellStyle.setFillForegroundColor(IndexedColors.LIGHT_YELLOW.getIndex());
        cellStyle.setBorderBottom(BorderStyle.THIN);
        cellStyle.setBorderLeft(BorderStyle.THIN);
        cellStyle.setBorderRight(BorderStyle.THIN);
        cellStyle.setBorderTop(BorderStyle.THIN);
        cellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        WriteFont contentWriteFont = new WriteFont();
        // 字体大小
//        contentWriteFont.setFontHeightInPoints((short)20);
        cellStyle.setWriteFont(contentWriteFont);
        return cellStyle;
    }

}
